


local Game = {}

local resource_definitions = {

	hudFont = {

		type = RESOURCE_TYPE_FONT,
		fileName = 'fonts/OCR A Std.ttf',
		glyphs = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 _-,.?!",
		fontSize = 25,
		dpi = 160
	},

	green_patt = {

		type = RESOURCE_TYPE_IMAGE,
		fileName = '16green_patt.png',
		width = 16, height = 16
	},

	metal_wall = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'metal-wall.png',
		width = 16, height = 16
	},
	
	space = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = '16space.png',
		width = 128, height = 128
	
	},
	
	base_entity = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = '16aqua-black.png',
		width = 16, height =16
	},
	
	base_actor = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'human_f.png',
		width = 8, height = 8
	
	},
	
	bot_actor = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'bot.png',
		width = 16, height = 16
	
	},
	
	repair_bot_actor = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'preacher-bot.png',
		width = 16, height = 16
	
	},
	
	bot_hatch = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'bot_hatch.png',
		width = 16, height = 16
	
	},
	
	control_panel = {
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = 'con_pan.png',
		tileMapSize = {4, 1}
	
	},
	
	metal_door = {
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = 'metal_door.png',
		tileMapSize = {2, 1}
	
	},
	
	thruster = {
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = '16x32thruster.png',
		tileMapSize = { 2, 1 }
	
	},
	
	airlock_door = {
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = 'airlock_doors.png',
		tileMapSize = { 2, 1 }
	
	},
	
	fuel_cell = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = '16fuelcell.png',
		width = 16, height = 16
	
	},
	
	wires = {
	
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = 'wires.png',
		tileMapSize = { 16, 1 }
	
	},
	
	air_tubes = {
	
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = 'blue_tubes.png',
		tileMapSize = { 16, 1 }
	
	},
	
	waste_tubes = {
	
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = 'orange_tube.png',
		tileMapSize = { 16, 1 }
	
	},
	
	supply_tubes = {
	
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = 'yellow_tube.png',
		tileMapSize = { 16, 1 }
	
	},
	
	water_tubes = {
	
		type = RESOURCE_TYPE_TILED_IMAGE,
		fileName = 'matte_blue_tube.png',
		tileMapSize = { 16, 1 }
	
	},
	
	food_station = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'food_station.png',
		width = 16, height = 16	
	
	},
	
	recycler = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'recycler.png',
		width = 16, height = 16	
	
	},
	
	oxygen_tanks = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'oxygen_tanks.png',
		width = 16, height = 16	
	
	},
	
	water_tanks = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'water_tanks.png',
		width = 16, height = 16	
	
	},
	
	space_toilet = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'space_toilet.png',
		width = 16, height = 16	
	
	},
	
	sleep_tube = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'sleep_tube.png',
		width = 16, height = 16
	
	
	},
	
	--[[
	control_panel_1 = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'con_pan_1.png',
		width = 16, height = 16
	
	},
	
	control_panel_2 = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'con_pan_2.png',
		width = 16, height = 16
	
	},
	
	control_panel_3 = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'con_pan_3.png',
		width = 16, height = 16
	
	},
	
	metal_door_1 = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'metal_door_1.png',
		width = 16, height = 16
	
	},
	
	metal_door_2 = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'metal_door_1.png',
		width = 16, height = 16
	
	},
	
	airlock_door_1 = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'airlock_door_1.png',
		width = 16, height = 16
	
	},
	
	airlock_door_2 = {
		type = RESOURCE_TYPE_IMAGE,
		fileName = 'airlock_door_2.png',
		width = 16, height = 16
	
	},
	
	]]
}



local background_objects = {
	--[[
	background = {
		position = { 0, 70 },
		parallax = { 0.05, 0.05 }
	},

	farAway = {
		position = {0, 50 },
		parallax = {0.1, 0.1}
	},

	main = {
		position = {0, -75},
		parallax = {1, 1}
	},

	]]
}

local scene_objects = {

	floor = {
		type = MOAIBox2DBody.STATIC,
		position = {0, -WORLD_RESOLUTION_Y/2},
		friction = 0,
		size = {2 * WORLD_RESOLUTION_X, 10 },
	},
	platform1 = {
		type = MOAIBox2DBody.STATIC,
		position = { 100, -50 },
		friction = 0,
		size = { 100, 20 }
	},

}



function Game:start()
	--initial setup
	self:initialize()
	
	local prevElapsedTime = MOAISim.getDeviceTime()
	local elapsedTime = 0

	while (true) do
		--self:processInput() -- deprecated
		local currElapsedTime = MOAISim.getDeviceTime()
		elapsedTime = currElapsedTime-prevElapsedTime
		prevElapsedTime = currElapsedTime
		self:update ( elapsedTime )
		coroutine.yield() -- coroutine block allows program to
		--complete a simulation step before checking for input
		--again
	end

end

function Game:initialize ()
	-- init camera
	self.camera = MOAICamera2D.new()
	self.camera:setPiv(CENTER_G_VIEW_X, CENTER_G_VIEW_Y)
	
	print("GAME camera world loc " .. self.camera:getWorldLoc())
	-- make layers
	self:setupLayers ()
	
	self.current_map = 1
	self.load_reveal = 0
	
	self.selected_construct = {}
	

	self.num_keys = {
		['one'] = 1,
		['two'] = 2,
		['three'] = 3,
		['four'] = 4,
		['five'] = 5,
		['six'] = 6,
		['seven'] = 7,
		['eight'] = 8,
		['nine'] = 9,
		['zero'] = 0
	}

	self.alpha_keys = {
		['a'] = 'a',
		['b'] = 'b',
		['c'] = 'c',
		['d'] = 'd',
		['e'] = 'e',
		['f'] = 'f',
		['g'] = 'g',
		['h'] = 'h',
		['i'] = 'i',
		['j'] = 'j',
		['k'] = 'k',
		['l'] = 'l',
		['m'] = 'm',
		['n'] = 'n',
		['o'] = 'o',
		['p'] = 'p',
		['q'] = 'q',
		['r'] = 'r',
		['s'] = 's',
		['t'] = 't',
		['u'] = 'u',
		['v'] = 'v',
		['w'] = 'w',
		['x'] = 'x',
		['y'] = 'y',
		['z'] = 'z',
	}

	self.punc_keys = {
		['tilde'] = '~',
		['colon'] = ':',
		['question'] = '?',
		['space'] = ' ',
		['l_sq_br'] = '[',
		['r_sq_br'] = ']',
	}
	
	
	--[[
	self.layer = MOAILayer2D.new ()
	self.layer:setViewport( viewport )
	self.layer:setCamera( self.camera )
	]]

	-- initialize input manager
	InputManager:initialize()
	-- load resources
	ResourceDefinitions:setDefinitions (resource_definitions)
	
	

	MapManager:initialize()
	--MapManager:path_update_grid( MapManager:add_map(MAP_HEIGHT,
	--	MAP_WIDTH, TILE_SIZE, TILE_SIZE, 'cell_auto', 1) )
	
	
	
	--MapManager:quick_map( MAP_HEIGHT, MAP_WIDTH, TILE_SIZE,
	--	TILE_SIZE, "cell_auto", 2 )
	
	--self:space_bg() !!!
		
	EntityManager:initialize()
	
	--ConstructManager = CM.new()
	--setmetatable(ConstructManager, CM.mt)
	ConstructManager:initialize()
	LifeManager:initialize()
	GuiManager:initialize()
	LocationManager:initialize()
	--LifeManager = LM.new()
	--setmetatable(LifeManager, LM.mt)
	
	--local ship = Ship:new(ShipLayouts.a, 20, 20)
	
	--local ship2 = Ship:new(ShipLayouts.a, 200, 20)
	
	--ConstructManager.constructs[1]:seekRot(1024, 10)
	
	--ConstructManager.constructs[2]:seekRot(1024, 10)
	
	--local ship = ConstructManager:spawn_ship(ShipLayouts.a, 40, 100, ShipLayouts.offsets.a, ShipLayouts.tube_map.a)
	
	--local ship2 = ConstructManager:spawn_ship(ShipLayouts.b, 200, 300, ShipLayouts.offsets.b, ShipLayouts.tube_map.b)
	
	--local dock = ConstructManager:spawn_dock(160, 95, 10)
	
	--local dock2 = ConstructManager:spawn_dock(160, 160, 5)
	
	--local tridock = ConstructManager:spawn_tridock( 40, 40, 10, 10 )
	--local ship3 = ConstructManager:spawn_ship(ShipLayouts.b, 250, 300, ShipLayouts.offsets.b, ShipLayouts.tube_map.b)
	--local ship4 = ConstructManager:spawn_ship(ShipLayouts.b, 350, 300, ShipLayouts.offsets.b, ShipLayouts.tube_map.b)
	--local ship5 = ConstructManager:spawn_ship(ShipLayouts.b, 450, 300, ShipLayouts.offsets.b, ShipLayouts.tube_map.b)
	
	--tridock:hooker( ship3, ship, ship2)
	--dock2:hooker( ship4, dock )
	--dock:hooker( nil, ship)
	
	LocationManager:new_loc("planet")
	
	--ship:hide_network(SUPPLY_PIPE_TYPE)
	
	--ship:show_network(WIRE_TYPE)
	
	--tridock:moveLoc(-200, 0, tridock.dock_time)
	
	
	--LifeManager.humans[2]:path_to_loc(6, 6)
	
	--dock:unhook( ship, ship2 )
	
	--ship:seekLoc( 400, 400, ship.dock_time)
	--ship2:seekLoc( 700, 700, ship2.dock_time)
	
	--coroutine.yield()
	--ship:seekLoc(20, 700, 10)
	
	--ship2:seekRot( 420, 5 )
	
	--ship2:setRot(96)
	
	--ship:docks(ship2)
	
	--ship:dock_cons( ship2 )
    
	--ship:moveLoc(600, 600, 30)
	--ship.transform:moveRot( 2048, 30 )
	--ship.transform:setLoc( 200, 200 )
	
    --ship.parts.parent.prop:seekLoc(600, 600, 30)
	
	--EntityManager:spawn("repair bot", 30, 30)
		
	--self:populateBackground()
	--self:loadBackground()
	--PhysicsManager:initialize( self.layers.walkBehind )
	--self:loadScene()
	--Character:initialize(self.layers.main)
	HUD:initialize()

	--AudioManager:initialize()
	--AudioManager:play( 'backgroundMusic' )

	print("GAME camera loc : ", self.camera:getLoc())
	
	local end_entry_point
	
	-- everything is loaded, enter initial state
	self.initial_state = true
	self.update_ready = true
	GS = GameState:new()
	GS:gotoState('Menu')
	
	

end

function Game:update (dt)
	local upd_func = function(self, dt)
		HUD:update()
		InputManager:update_keys()
		
		if Game.state == "gameplay" then
			Actor.update(dt)
			ConstructManager:update(dt)
		end
		ThreadManager:update()
		TimerManager:update()
		local upd_togg = function(self)
			
			self.update_ready = true
		
		end
		upd_togg(self)
	end
	
	if self.update_ready then
		self.update_ready = false
		
		
		
		GAME_UPD_T = MOAICoroutine.new()
		GAME_UPD_T:run(upd_func, self, dt)
		
		
		
	end
	
	
end

function Game:check_clickable(x, y)

	if self.state == "gameplay" then
		local ships = ConstructManager:get_ships()
		local first_select = false
		
		for i = 1, #ships do

			-- check workstations
			for j = 1, #ships[i].stations.cat do
				local a
				local stat = ships[i].stations.cat[j]
				-- if within a workstation
				
				if stat:check_gui() then			
					stat:close_gui(stat:get_gui_id())
				elseif stat:inside(x, y) and not first_select then
					first_select = true
					stat:open_gui()
					print("INSIDE .. " .. stat.type)			
				end
			
			end
		
		end
	elseif self.state == "menu" then
		if menu_data then
			if menu_data.gui then
				for i = 1, #menu_data.gui do
					--print("clicked: x " .. x .. " y " .. y)
					print("menu x: ".. menu_data.x[i] .. " y: ".. menu_data.y[i] .. " x2 ".. menu_data.x2[i] .. " y2 " .. menu_data.y2[i])
					if x >= menu_data.x[i] and x <= menu_data.x2[i] and y >= menu_data.y[i] and y <= menu_data.y2[i] then
						local text = menu_data.gui[i]:getText()
						local options = {
							["New Game"] = function() GS:gotoState('Gameplay') end,
							["Continue"] = function() GS:gotoState('Gameplay') end,
							["Quit"] = function() os.exit() end,
						
						}
						
						options[text]()
					
					end
				end
			end
		end
	
	
	end

end

function Game:belongsToScene ( fixture )

	for key, object in pairs ( self.objects ) do

		if object.fixture == fixture then

			return true

		end

	end

	return false

end

function Game:loadScene()

	self.objects = {}
	for key, attr in pairs(scene_objects) do
		local body = PhysicsManager.world:addBody(attr.type)
		body:setTransform( unpack(attr.position) );
		width, height = unpack(attr.size);
		local fixture = body:addRect(-width/2, -height/2,
			width/2, height/2 )
		fixture:setFriction ( attr.friction )

		self.objects[key] = { body = body, fixture = fixture }
	end

end

function Game:setupLayers()

	self.layers = {}
	self.layers.background = MOAILayer2D.new ()
	self.layers.farAway = MOAILayer2D.new ()
	self.layers.midGround = MOAILayer2D.new()
	self.layers.main = MOAILayer2D.new ()
	self.layers.walkBehind = MOAILayer2D.new ()
	self.layers.effects = MOAILayer2D.new()
	self.layers.hud = MOAILayer2D.new()

	for key, layer in pairs ( self.layers ) do
		layer:setViewport( g_viewport )
		layer:setCamera( self.camera )
	end

	local renderTable = {
		self.layers.background,
		self.layers.midGround,
		self.layers.farAway,
		self.layers.main,
		self.layers.walkBehind,
		self.layers.effects,
		self.layers.hud,
	}

	MOAIRenderMgr.setRenderTable(renderTable)

end


function Game:render_layer( layer_a, layer_bnum, pos)

	local renderTable = MOAIRenderMgr.getRenderTable()
	
	if layer_bnum then table.remove(renderTable, layer_bnum) end
	
	if renderTable then
		if pos then table.insert(renderTable, pos, layer_a)
		else table.insert(renderTable, layer_a) end
	end
	
	MOAIRenderMgr.setRenderTable( renderTable )
	

end

function Game:space_bg()
	self.space_tiles = {}
	
	local hwid = 4
	
	local t = {}
	t.layer = MOAILayer2D.new()
	t.layer:setViewport(g_viewport)
	t.layer:setCamera( Game.bg_camera )
	t.layer:setParallax(0.1, 0.1)
	
	for y = -hwid, hwid do
		
		for x = -hwid, hwid do
			
			
			t.deck = ResourceManager:get('space')
			t.prop = MOAIProp2D.new()
			t.prop:setDeck(t.deck)
			t.prop:setLoc(x*(TILE_SIZE*8), y*(TILE_SIZE*8))
			if not Game.bg_camera then Game.bg_camera = MOAICamera2D.new() end
			
			
						
			t.layer:insertProp(t.prop)
			
			
			
			
			--print(t.prop:getLoc())
			
			local offset = hwid * 2
			local iter = #self.space_tiles + 1
			self.space_tiles[iter] = t.prop
		
		end	
	end
	
	self:render_layer(t.layer)
end

function Game:sparkle_space_bg()
	
	print("GAME in sparkle space bg")
		
	local props = self:props_in_camera( self.space_tiles, cam_points)
	
	local rng = mwc()
	
	for i = 1, #props do
	
		local r = rng:random()
		local g = rng:random()
		local b = rng:random()
		local a = rng:random()
		local t = rng:random(1, 5)
		
		props[i]:seekColor(r, g, b, a, t)
	
	end

end

function Game:start_uts()
	
	local t = TM.uts_t
	t:setSpan(10)
	t:setMode(MOAITimer.LOOP)
	t:setListener( MOAITimer.EVENT_TIMER_LOOP,
		function(self, times)
			
			TM:uts_minute()
			print(TM.uts)
		
		end
	
	)
	
	t:start()

end

function Game:repeat_call( delay, func, ...)
	local timer = MOAITimer.new()
	timer:setSpan( delay )
	timer:setListener( MOAITimer.EVENT_TIMER_LOOP,
		function()
			local t = MOAICoroutine.new()
			t:run (func ( unpack ( arg )) )
		end  )
	timer:start()
	
	if not self.timers then
		self.timers = {}
	end
	
	self.timers[#self.timers+1] = timer

end

function Game:get_camera_points()

	local yiter = G_VIEW_SIZE_Y/TILE_SIZE
	local xiter = G_VIEW_SIZE_X/TILE_SIZE
	local cx, cy, cz = self.camera:getLoc()
	local cam_points = {}
	
	for y = 1, yiter do
		for x = 1, xiter do
		
			local ptx = cx + (x * TILE_SIZE)
			local pty = cy + (y * TILE_SIZE)
			local iter = #cam_points+1
			
			cam_points[iter] = {}
		
			cam_points[iter].x = ptx
			cam_points[iter].y = pty
			cam_points[iter].z = 0
			
			print("GAME get_camera_points cam p: " .. ptx .. " " .. pty)
		
		
		end
	
	end
	
	return cam_points

end

function Game:props_in_camera( props )
	
	local prop_list = {}
	
	local cam_points = self:get_camera_points()
	
	for i = 1, #props do
		for j = 1, #cam_points do
		
			local x, y, z = 
				cam_points[j].x, 
				cam_points[j].y, 
				cam_points[j].z
		
			if props[i]:inside(x, y, z) then
				
				print("GAME props_in_camera prop at : " .. x .. " " .. y .. " " .. z )
				
				prop_list[#prop_list+1] = props[i]
			
			end
		
		end
	
	end
	
	return prop_list

end

function Game:populateBackground()

	local map = MapManager.maps[self.current_map]

	self.background = {}

	for y = 1, map.height do
		for x = 1, map.width do
			local t = {}
			--print(map.height, map.width)
			local n = map.grid:getTile(x, y)
			if n == WALL_TILE then
				t.deck = ResourceManager:get('metal_wall')
			elseif n == FLOOR_TILE then
				t.deck = ResourceManager:get('green_patt')
			elseif n == SPACE_TILE then
				--t.deck = ResourceManager:get('space')
			else
				print('ERROR: invalid tile type')
			end

			t.prop = MOAIProp2D.new()
			t.prop:setDeck(t.deck)
			t.prop:setLoc(x*TILE_SIZE,
				y*TILE_SIZE)

			map.layer:insertProp(t.prop)
			--self.layers['background']:setParallax( 1,1 )
			map.layer:setParallax( 1, 1 )
			--map.layer:setCamera(self.camera)

			local s = "t"..x.."x"..y

			self.background[s] = t

		end
	end
end

function Game:loadBackground()

	self.background = {}

	for name, attributes in pairs(background_objects) do
		local b = {}
		-- create deck from table key
		b.deck = ResourceManager:get( name )
		-- create prop
		b.prop = MOAIProp2D.new ()
		-- assign prop to deck
		b.prop:setDeck(b.deck)
		-- set prop loc to position attribute
		b.prop:setLoc( unpack(attributes.position) )
		-- insert prop to layer and set parallax
		self.layers[name]:insertProp( b.prop )
		self.layers[name]:setParallax( unpack(attributes.parallax))

		self.background[name] = b

	end

end

function Game:move_camera(dir)

	local x, y, z = self.camera:getLoc()

	if dir == 'right' then self.camera:setLoc(x + TILE_SIZE*0.5, y, z) end
	if dir == 'left' then self.camera:setLoc(x - TILE_SIZE*0.5, y, z ) end	
	if dir == 'up' then self.camera:setLoc(x, y - TILE_SIZE*0.5, z) end
	if dir == 'down' then self.camera:setLoc(x, y+ TILE_SIZE*0.5, z ) end
	if dir == 'in' then self:zoom_in() end
	if dir == 'out' then self:zoom_out() end
	if dir == 'rl' then self:rot_cam_left() end
	if dir == 'rr' then self:rot_cam_right() end
	
	--print(self.camera:getLoc())
end


function Game:keyPressed( key, down )

	if key == 'right' then Character:moveRight (down) end
	if key == 'left' then Character:moveLeft(down) end
	if key == 'up' then Character:jump(down) end


end

function Game:control_view ( key, down )

	local x, y, z = self.camera:getLoc()		

	if down then

		--print(key)
		--if key == 'right' or key == 'left' or key == 'up' or key == 'down' then
		--	self:move_camera(key)
		--end
		if self.num_keys[key] then end
		if self.alpha_keys[key] then end
		if self.punc_keys[key] then end

		
		if key == 'save' then MapManager:save_map( self.current_map ) end
		if key == 'load' then

			if not HUD.d_maps then
				HUD:display_maps()
			else
				HUD:remove_map_display()
			end

		end
		
		if not HUD.console then
		
			if key == 'esc' and Game.state == 'menu' then
				
				os.exit()
				
			elseif key == 'esc' and Game.state == 'gameplay' then
			
				--os.exit()
				GS:gotoState('Menu')
			
			end
		
		end
		
		if Game.selected_construct then
			if key == 'waste' or key == 'supply' 
				or key == 'water' or key == 'oxy' 
				or key == 'wires' then
				
				local types = {
					['waste'] = WASTE_PIPE_TYPE,
					['supply'] = SUPPLY_PIPE_TYPE,
					['water'] = WATER_PIPE_TYPE,
					['oxy'] = OXYGEN_HOSE_TYPE,
					['wires'] = WIRE_TYPE,
				}
				
				local t = types[key]
				if Game.selected_construct.toggle_network_vis then
					Game.selected_construct:toggle_network_vis(t)
				end
				
			
			end
		end

		if key == 'tilde' then
			if not HUD.console then
				local str = HUD:assemble_console()
				HUD:display_console()
			else
				HUD:remove_console_display()
			end

		end
		
		if key == 'l_sq_br' then
		
			self:zoom_out()
		
		end
		
		if key == 'r_sq_br' then
		
			self:zoom_in()
			
		end

		if HUD.d_maps then



			if self.num_keys[key] then

				HUD:remove_map_display()
				MapManager:load_map( USER_NAME, self.num_keys[key], 1 )

			end

		end

		if HUD.console then

			if self.num_keys[key] then

				HUD.console.text = HUD.console.text .. self.num_keys[key]

			end

			if self.alpha_keys[key] then

				HUD.console.text = HUD.console.text .. self.alpha_keys[key]

			end

			if self.punc_keys[key] then
				if self.punc_keys[key] ~= 'tilde' then
					HUD.console.text = HUD.console.text .. self.punc_keys[key]
				end

			end

			if key == 'enter' then

				HUD:add_console( HUD.console.text )
				HUD.console.text = ""

			end
			
			if key == 'backspace' then
				
				local t_len = HUD.console.text:len()
				
				HUD.console.text = HUD.console.text:sub(1, t_len-1)
			
			end



		end

	end
	--[[
	x, y, z = self.camera:getLoc()

	if x < 0 then self.camera:setLoc( 0, y, z) end
	if x > 72 then self.camera:setLoc( 72, y, z) end
	if y < 0 then self.camera:setLoc(x, 0, z) end
	if y > 224 then self.camera:setLoc(x, 224, z) end
	]]

	

end

--[==[ deprecated, remains for reference
function Game:processInput()

	local x, y = InputManager:deltaPosition()
	--uncomment to move camera (uncontrollably fast) with mouse
	--self.camera:moveLoc(x, 0, 0.5, MOAIEaseType.LINEAR)
end
]==]


function Game:resource_from_number( num )

	local result
	
	local sources = {
		[0] = function() return 'blank' end,
		[SPACE_TILE] = function() return 'space' end,
		[WALL_TILE] = function() return 'metal_wall' end,
		[FLOOR_TILE] = function() return 'green_patt' end,
		[CONTROL_PANEL] = function() return 'control_panel' end,	
		[DOOR_TILE] = function() return 'metal_door' end,
		[AIRLOCK_TILE] = function() return 'airlock_door' end,
		[HOOK_TILE] = function() return 'hook_tile' end,
		[THRUSTER_TILE] = function() return 'thruster' end,
		[FUEL_CELL] = function() return 'fuel_cell' end,
		[FOOD_STATION] = function() return 'food_station' end,
		[RECYCLER] = function() return 'recycler' end,
		[OXYGEN_TANKS] = function() return 'oxygen_tanks' end,
		[WATER_TANKS] = function() return 'water_tanks' end,
		[SPACE_TOILET] = function() return 'space_toilet' end,
		[SLEEP_TUBE] = function() return 'sleep_tube' end,
	
	}
	if not sources[num] then
		result = sources[0]()
	else
		result = sources[num]()
	end
	
	if result then return result else 
	local msg = "ERROR GAME:resource_from_number invalid resource number"; 
	print(msg);return msg end


end

function Game:isWorkstation( num )
	
	local result
	
	local sources = {
		[0] = function() return false end,
		[CONTROL_PANEL] = function() return true end,
		[FUEL_CELL] = function() return true end,
		[FOOD_STATION] = function() return true end,
		[RECYCLER] = function() return true end,
		[OXYGEN_TANKS] = function() return true end,
		[WATER_TANKS] = function() return true end,
		[SPACE_TOILET] = function() return true end,
		[SLEEP_TUBE] = function() return true end,
	
	}
	
	if not sources[num] then
		result = sources[0]()
	else
		result = sources[num]()
	end
	
	if result then return result else
	return false end



end

function Game:zoom_in()

	self.camera:moveScl( 0.05, 0.05, 0.1)

end

function Game:zoom_out()

	self.camera:moveScl( -0.05, -0.05, 0.1)
end

function Game:rot_cam_left()
	local rot = self.camera:getRot()
	--print(Grot)
	self.camera:moveRot( 1, 0.1 )
end

function Game:rot_cam_right()
	local rot = self.camera:getRot()
	--print(rot)

	self.camera:moveRot( -1, 0.1)
end

--local x, y, z = self.camera:getLoc()
--if dir == 'right' then self.camera:setLoc(x + TILE_SIZE*0.5, y, z) end
--if dir == 'left' then self.camera:setLoc(x - TILE_SIZE*0.5, y, z ) end	
--if dir == 'up' then self.camera:setLoc(x, y - TILE_SIZE*0.5, z) end
--if dir == 'down' then self.camera:setLoc(x, y+ TILE_SIZE*0.5, z ) end

function Game:move_cam_right()
	local rot = self.camera:getRot()
	
	--if rot 

end

function Game:move_cam_left()
	local rot = self.camera:getRot()

end
function Game:move_cam_up()
	local rot = self.camera:getRot()

end
function Game:move_cam_down()
	local rot = self.camera:getRot()

end



function setParent( prop, parent, mode )

		local action = {
		
			['t'] = function(prop, parent)
				prop:setAttrLink( MOAIProp2D.INHERIT_TRANSFORM, parent, MOAIProp2D.TRANSFORM_TRAIT ) 			
			end,
			
			['c'] = function(prop, parent)
				prop:setAttrLink ( MOAIProp2D.INHERIT_COLOR, parent, MOAIProp2D.COLOR_TRAIT ) 			
			end,
			
			['v'] = function(prop, parent)			
				prop:setAttrLink( MOAIProp2D.ATTR_VISIBLE, parent, MOAIProp2D.ATTR_VISIBLE ) 			
			end,
			
			['tc'] = function(prop, parent)			
				prop:setAttrLink( MOAIProp2D.INHERIT_TRANSFORM, parent, MOAIProp2D.TRANSFORM_TRAIT ) 
				prop:setAttrLink ( MOAIProp2D.INHERIT_COLOR, parent, MOAIProp2D.COLOR_TRAIT ) 			
			end,
			
			['tv'] = function(prop, parent)			
				prop:setAttrLink( MOAIProp2D.INHERIT_TRANSFORM, parent, MOAIProp2D.TRANSFORM_TRAIT ) 
				prop:setAttrLink( MOAIProp2D.ATTR_VISIBLE, parent, MOAIProp2D.ATTR_VISIBLE ) 			
			end,
			
			['tvc'] = function (prop, parent)			
				prop:setAttrLink( MOAIProp2D.INHERIT_TRANSFORM, parent, MOAIProp2D.TRANSFORM_TRAIT ) 
				prop:setAttrLink ( MOAIProp2D.INHERIT_COLOR, parent, MOAIProp2D.COLOR_TRAIT ) 
				prop:setAttrLink( MOAIProp2D.ATTR_VISIBLE, parent, MOAIProp2D.ATTR_VISIBLE ) 			
			end,
			
			['cv'] = function (prop, parent)			
				prop:setAttrLink ( MOAIProp2D.INHERIT_COLOR, parent, MOAIProp2D.COLOR_TRAIT ) 
				prop:setAttrLink( MOAIProp2D.ATTR_VISIBLE, parent, MOAIProp2D.ATTR_VISIBLE ) 			
			end,		
		}
	if prop and parent and mode then	
		print("GAME setParent setting parent")
		action[mode](prop, parent)		
    end
end

-- freeze the coroutine for a different time
function sleepCoroutine (time)
	local timer = MOAITimer.new ()
	timer:setSpan ( time )
	timer:start()
	MOAICoroutine.blockOnAction ( timer )

end



return Game
